#coding=utf-8

from fastapi import APIRouter, HTTPException
from services.enums.general import StudentInfo
from orm.models import *

# 在tortoise模式下， 必须用异步的模式async + await 两个关键字来实现。

student = APIRouter()

@student.get("/", summary="查询所有学生")
async def get_all_student():
    # 基础查询所有记录
    # stu = await Students.all()   # 返回的是Queryset, [Students(), Students(),...]
    # 一对多，多对多的查询
    stu = await Students.all().values("name","c_no__name")      # 一对多
    stu = await Students.all().values("name", "c_no__name", "c_subject__subject_name")    # 多对多
    return {
        "code": 1,
        "message": "成功",
        "result": stu
    }
    
@student.get("/{no}", summary="查询部分学生")
async def get_student_by_sno(no: int):
    # stu = await Students.filter(no=no)  # 返回的是Queryset
    # # 模糊查询
    # stu = await Students.filter(no__gt=no)  # 返回的是no > 入参值 的Queryset
    # stu = await Students.filter(no__in=[1,3,5,7,9]) # 返回的是no in [1,3,5,7,9]的Queryset
    # stu = await Students.filter(no__range=[1,9]) # 返回的是no in range[1,9]的Queryset
    # values查询
    # stu = await Students.all().values("name")  # [{'name': xxx},...]
    # stu = await Students.filter(no__gt=no).values("no","name")  # [{'no':xx, 'name': xxx},...]
    # 精确查询
    stu = await Students.get(no=no)   # 返回的是一个模型类对象， Student()
    # 查询单个学生的外键信息
    # print(await stu.c_no.values("name"))                                # 一对多查询
    # print(await stu.c_subject.all().values("subject_name","addr"))      # 多对多查询
    # stu = await Students.get(no=no)
    stu_class = await stu.c_no.values("name")
    stu_subjects = await stu.c_subject.all().values("subject_name")
    data = {
        "no": stu.no,
        "name": stu.name,
        "class": stu_class.get("name"),
        "subjects": [item.get("subject_name") for item in stu_subjects]
    }
    return {
        "code": 1,
        "message": "成功",
        "result": data
    }

@student.post("/", summary="新增学生")
async def create_student(student_info: StudentInfo):
    # # 方法1，返回值为空
    # stu = Students(name=student_info.name, password=student_info.password, c_no_id = student_info.c_no_id )
    # stu_record = await Students.save(stu)  
    # 方法2， 返回值为插入数据表的最新的记录
    stu_record = await Students.create(name=student_info.name, password=student_info.password, c_no_id = student_info.c_no_id )
    # 多对多关系的绑定
    stu_courses = await Courses.filter(id__in=student_info.c_subject_id)    # 获取有效的科目ID信息, 返回的是Queryset
    await stu_record.c_subject.clear()                                      # 将添加的学生可能存在的历史的科目给清掉后，重新添加
    await stu_record.c_subject.add(*stu_courses)                            # 新增的学生对象.model中的多对多的字段名.add(*args) 将args转换成一个一个元素进行添加
    return {
        "code": 1,
        "message": "成功",
        "result": stu_record
    }   


@student.put("/{no}", summary="编辑学生")
async def modify_student(no:int, student_info: StudentInfo):
    stu_upd_info = dict(student_info)
    stu_subject_list = stu_upd_info.pop("c_subject_id")
    await Students.filter(no=no).update(**stu_upd_info)
    stu = await Students.get(no=no)
    stu_subject = await Courses.filter(id__in=stu_subject_list)
    await stu.c_subject.clear()
    await stu.c_subject.add(*stu_subject)
    return {
        "code": 1,
        "message": "成功",
        "result": stu
    } 


@student.delete("/{no}", summary="删除学生")
async def del_student(no:int):
    deleted_count = await Students.filter(no=no).delete()
    if not deleted_count:
        raise HTTPException(status_code=404, detail="学号{}的学生不存在".format(no))
    return {
        "code": 1,
        "message": "成功",
        "deleted_count": deleted_count
    } 
